package com.wujunshen.dumpling.core.engine.velocity;

import com.wujunshen.dumpling.common.utils.Assert;
import com.wujunshen.dumpling.core.engine.AbstractTemplateEngine;
import com.wujunshen.dumpling.core.engine.EngineConfig;
import com.wujunshen.dumpling.database.metadata.model.Data;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

import static com.wujunshen.dumpling.common.constant.Constants.DEFAULT_ENCODING;
import static com.wujunshen.dumpling.core.engine.EngineTemplateType.VELOCITY;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.velocity.runtime.RuntimeConstants.*;

/**
 * velocity template
 *
 * @author frankwoo
 */
@Slf4j
public class VelocityTemplateEngine extends AbstractTemplateEngine {
  /** DATA */
  private static final String DATA = "_data";
  /** VelocityEngine */
  private static VelocityEngine velocityEngine;

  {
    // 初始化模板引擎
    velocityEngine = new VelocityEngine();
    // 如果存在自定义模板
    if (StringUtils.isNotBlank(getEngineConfig().getCustomTemplate())) {
      velocityEngine.setProperty(
          "string.resource.loader.class",
          "org.apache.velocity.runtime.resource.loader.StringResourceLoader");
    } else {
      velocityEngine.setProperty(
          "file.resource.loader.class",
          "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
    }
    velocityEngine.setProperty(FILE_RESOURCE_LOADER_PATH, "");
    velocityEngine.setProperty(ENCODING_DEFAULT, DEFAULT_ENCODING);
    velocityEngine.setProperty(INPUT_ENCODING, DEFAULT_ENCODING);
    velocityEngine.setProperty("file.resource.loader.unicode", "true");
  }

  /**
   * 构造函数
   *
   * @param templateConfig {@link EngineConfig }
   */
  public VelocityTemplateEngine(EngineConfig templateConfig) {
    super(templateConfig);
  }

  /**
   * 生成文档
   *
   * @param data {@link Data}
   */
  @SneakyThrows
  @Override
  public void produce(Data data, String documentName) {
    Assert.isNotNull(data);
    Template template;
    // get template path
    String path = getEngineConfig().getCustomTemplate();
    // 如果自定义了模板
    if (StringUtils.isNotBlank(path)) {
      template = velocityEngine.getTemplate(path, DEFAULT_ENCODING);
    } else {
      // 没有自定义模板，使用核心包自带
      template =
          velocityEngine.getTemplate(
              VELOCITY.getTemplateDir()
                  + getEngineConfig().getFileType().getTemplateNamePrefix()
                  + VELOCITY.getSuffix(),
              DEFAULT_ENCODING);
    }
    // output
    try (FileOutputStream outStream = new FileOutputStream(getFile(documentName));
        OutputStreamWriter writer = new OutputStreamWriter(outStream, UTF_8);
        BufferedWriter sw = new BufferedWriter(writer)) {
      // put data
      VelocityContext context = new VelocityContext();
      context.put(DATA, data);
      // generate
      template.merge(context, sw);
      // open the output directory
      openOutputDir();
    }
  }
}
